using System;
using Volo.Abp.Domain.Entities.Auditing;

namespace BW.WMS.WareHouseManage
{
    /// <summary>
    /// 库位物品实体 - 用于跟踪库位中存储的物品
    /// </summary>
    public class LocationItem : FullAuditedEntity<Guid>
    {
        /// <summary>
        /// 库位ID
        /// </summary>
        public Guid LocationId { get; set; }
        
        /// <summary>
        /// 物料ID
        /// </summary>
        public Guid MaterialId { get; set; }
        
        /// <summary>
        /// 批次号
        /// </summary>
        public string BatchNo { get; set; }
        
        /// <summary>
        /// 优品仓库编号
        /// </summary>
        public string ExternalCode { get; set; }
        
        /// <summary>
        /// 数量
        /// </summary>
        public int Quantity { get; set; }
        
        /// <summary>
        /// 锁定数量（被分配但未实际出库的数量）
        /// </summary>
        public int LockedQuantity { get; set; }
        
        /// <summary>
        /// 可用数量
        /// </summary>
        public int AvailableQuantity => Quantity - LockedQuantity;
        
        /// <summary>
        /// 生产日期
        /// </summary>
        public DateTime? ProductionDate { get; set; }
        
        /// <summary>
        /// 入库日期
        /// </summary>
        public DateTime InboundDate { get; set; }
        
        /// <summary>
        /// 有效期至
        /// </summary>
        public DateTime? ExpiryDate { get; set; }
        
        /// <summary>
        /// 状态 (0-正常，1-待检，2-冻结，3-不良)
        /// </summary>
        public int Status { get; set; }
        
        /// <summary>
        /// 来源单号（如入库单号）
        /// </summary>
        public string SourceDocumentNo { get; set; }
        
        /// <summary>
        /// 来源单据类型（1-入库单，2-退货单，3-转移单）
        /// </summary>
        public int SourceDocumentType { get; set; }
        
        /// <summary>
        /// 供应商ID
        /// </summary>
        public Guid? SupplierId { get; set; }
        
        /// <summary>
        /// 所有者ID
        /// </summary>
        public Guid? OwnerId { get; set; }
        
        /// <summary>
        /// 备注
        /// </summary>
        public string Remark { get; set; }
        
        /// <summary>
        /// 最近操作时间
        /// </summary>
        public DateTime? LastOperationTime { get; set; }
        
        /// <summary>
        /// 最近操作类型（1-入库，2-出库，3-移库，4-盘点）
        /// </summary>
        public int? LastOperationType { get; set; }
        
        // 导航属性
        public virtual Location Location { get; protected set; }
        public virtual Material Material { get; protected set; }
        
        protected LocationItem()
        {
        }
        
        public LocationItem(
            Guid id,
            Guid locationId,
            Guid materialId,
            int quantity,
            string batchNo = null,
            DateTime? expiryDate = null) : base(id)
        {
            LocationId = locationId;
            MaterialId = materialId;
            Quantity = quantity;
            BatchNo = batchNo;
            ExpiryDate = expiryDate;
            InboundDate = DateTime.Now;
            Status = 0; // 正常
        }
        
        /// <summary>
        /// 增加物品数量
        /// </summary>
        public void IncreaseQuantity(int amount)
        {
            if (amount <= 0)
            {
                throw new ArgumentException("增加的数量必须大于0", nameof(amount));
            }
            
            Quantity += amount;
            LastOperationTime = DateTime.Now;
            LastOperationType = 1; // 入库操作
        }
        
        /// <summary>
        /// 减少物品数量
        /// </summary>
        public void DecreaseQuantity(int amount)
        {
            if (amount <= 0)
            {
                throw new ArgumentException("减少的数量必须大于0", nameof(amount));
            }
            
            if (amount > AvailableQuantity)
            {
                throw new InvalidOperationException($"可用库存不足，当前可用:{AvailableQuantity}，请求:{amount}");
            }
            
            Quantity -= amount;
            LastOperationTime = DateTime.Now;
            LastOperationType = 2; // 出库操作
        }
        
        /// <summary>
        /// 锁定物品数量
        /// </summary>
        public void LockQuantity(int amount)
        {
            if (amount <= 0)
            {
                throw new ArgumentException("锁定的数量必须大于0", nameof(amount));
            }
            
            if (amount > AvailableQuantity)
            {
                throw new InvalidOperationException($"可用库存不足，当前可用:{AvailableQuantity}，请求:{amount}");
            }
            
            LockedQuantity += amount;
        }
        
        /// <summary>
        /// 解锁物品数量
        /// </summary>
        public void UnlockQuantity(int amount)
        {
            if (amount <= 0)
            {
                throw new ArgumentException("解锁的数量必须大于0", nameof(amount));
            }
            
            if (amount > LockedQuantity)
            {
                throw new InvalidOperationException($"锁定库存不足，当前锁定:{LockedQuantity}，请求解锁:{amount}");
            }
            
            LockedQuantity -= amount;
        }
    }
} 